//
// Created by zhouwd on 2019/5/14.
//
#include <jni.h>
#include <android/asset_manager_jni.h>
#include <android/log.h>
#include <cstdlib>
#include <cstring>
#include "render.h"
#include "encode.h"
#include "audio-ancode.h"
#include <pthread.h>
#include <fcntl.h>
#include <unistd.h>
#include "media-record.h"

#define LOG_TAG "CAMERA-RENDER"
#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)



static int mWidth = 720, mHeight = 1280;

Render *render;

MediaRecord *mediaRecord;
extern "C"
JNIEXPORT void JNICALL
Java_com_zhouwd_zcamera_JniUtil_sendFrameData(JNIEnv *env, jclass type, jbyteArray data_, jint width, jint height) {
    //ALOGE("Java_com_zhouwd_zcamera_PreviewRender_sendFrameData:");
    jbyte *data = env->GetByteArrayElements(data_, NULL);



    jsize size = env->GetArrayLength(data_);

    char* data1 = (char *)malloc(size);

    memcpy(data1, data, size);

    //encode->inputEncodeBuffer(data1, size);
    mediaRecord->encodeVideoData(data1, size);
    free(data1);

    render->updateFrameData(data);


    env->ReleaseByteArrayElements(data_, data, 0);

}


extern "C"
JNIEXPORT void JNICALL
Java_com_zhouwd_zcamera_JniUtil_resize(JNIEnv *env, jclass type, jint width, jint height) {
    ALOGE("Java_com_zhouwd_z_1camera_PreviewRender_resize:");
    // TODO
    render->resize();
}

extern "C"
JNIEXPORT void JNICALL
Java_com_zhouwd_zcamera_JniUtil_step(JNIEnv *env, jclass type) {
    //ALOGE("Java_com_zhouwd_z_1camera_PreviewRender_step: ");
    // TODO
    render->step();

}

extern "C"
char * getShaderFromAsset(AAssetManager* mgr, const char *mfile) {
    AAsset* assetFragmentShader = AAssetManager_open(mgr, mfile, AASSET_MODE_UNKNOWN);

    if(assetFragmentShader==NULL)
    {
        ALOGE(" %s","asset==NULL");
        return NULL;
    }
    /*获取文件大小*/
    off_t bufferSize = AAsset_getLength(assetFragmentShader);
    //ALOGE("file size : %d\n",bufferSize);
    char *buffer=(char *)malloc(bufferSize+1);
    buffer[bufferSize]=0;
    int numBytesRead = AAsset_read(assetFragmentShader, buffer, bufferSize);
    ALOGE("numBytesRead: %d",numBytesRead);
    ALOGE("buffer: %s",buffer);

    /*关闭文件*/
    AAsset_close(assetFragmentShader);

    return buffer;
}



extern "C"
JNIEXPORT jboolean JNICALL
Java_com_zhouwd_zcamera_JniUtil_init(JNIEnv *env, jclass type, jobject assetManager) {

    // TODO
    ALOGE("Java_com_zhouwd_z_1camera_PreviewRender_init111:");
    //encode = new Encode();
    //audioEncode = new AudioEncode();
    //int encodeResult = encode->init("");
    //int audioEncodeResult = audioEncode->init();
    //ALOGE("encodeResult > %d > audioEncodeResult > %d", encodeResult, audioEncodeResult);

    render = new Render();

    AAssetManager* mgr = AAssetManager_fromJava(env, assetManager);

    if(mgr==NULL)
    {
        ALOGE(" %s","AAssetManager==NULL");
        return JNI_FALSE;
    }

    const char *mPreviewFragmentShaderFile = "preview_fragment_shader.glsl";
    const char *mPreviewVertexShaderFile = "preview_vertex_shader.glsl";

    char *mPreviewFragmentShaderBuffer = getShaderFromAsset(mgr, mPreviewFragmentShaderFile);

    char *mPreviewVertexShaderBuffer = getShaderFromAsset(mgr, mPreviewVertexShaderFile);

    int ret;

    ret = render->init(mWidth, mHeight, mPreviewFragmentShaderBuffer , mPreviewVertexShaderBuffer);

    if (!ret){
        ALOGE("程序创建失败");
        return JNI_FALSE;
    }

    return JNI_TRUE;
}

extern "C"
JNIEXPORT jboolean JNICALL
Java_com_zhouwd_zcamera_JniUtil_startRecord(JNIEnv *env, jclass type, jobject startRecordParam) {

    // TODO
    ALOGE("Java_com_zhouwd_zcamera_JniUtil_startRecord");
    //encode->startEncode();
    mediaRecord->startRecord();
    return JNI_FALSE;
}


extern "C"
JNIEXPORT void JNICALL
Java_com_zhouwd_zcamera_JniUtil_stopRecord(JNIEnv *env, jclass type) {

    // TODO
    ALOGE("Java_com_zhouwd_zcamera_JniUtil_startRecord");
    //encode->stopEncode();
    mediaRecord->stopRecord();
    //audioEncode->stopEncode();
}

extern "C"
JNIEXPORT void JNICALL
Java_com_zhouwd_zcamera_JniUtil_sendAudioData(JNIEnv *env, jclass type, jbyteArray data_) {
    jbyte *data = env->GetByteArrayElements(data_, NULL);

    // TODO
    //ALOGE("Java_com_zhouwd_zcamera_JniUtil_sendAudioData");
    jsize size = env->GetArrayLength(data_);

    char* data1 = (char *)malloc(size);

    memcpy(data1, data, size);

    //audioEncode->encode(data1, size);
    mediaRecord->encodeAudioData(data1, size);
    free(data1);
    env->ReleaseByteArrayElements(data_, data, 0);
}

int output_fd;

extern "C"
JNIEXPORT jboolean JNICALL
Java_com_zhouwd_zcamera_JniUtil_initMediaRecord(JNIEnv *env, jclass type, jstring filename_) {
    const char *filename = env->GetStringUTFChars(filename_, 0);

    mediaRecord = new MediaRecord();
    ALOGE("Java_com_zhouwd_zcamera_JniUtil_initMediaRecord ---> 11111");
    // TODO
    output_fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0777);
    ALOGE("Java_com_zhouwd_zcamera_JniUtil_initMediaRecord --->11");
    int resutl = mediaRecord->init(output_fd);
    ALOGE("Java_com_zhouwd_zcamera_JniUtil_initMediaRecord resutl ---> %d" , resutl);
    env->ReleaseStringUTFChars(filename_, filename);

    return JNI_FALSE;
}

extern "C"
JNIEXPORT jboolean JNICALL
Java_com_zhouwd_zcamera_JniUtil_releaseMediaRecord(JNIEnv *env, jclass type) {

    delete(mediaRecord);
    mediaRecord->release();
    // TODO
    close(output_fd);
    return JNI_FALSE;
}